<script setup lang="ts">
import type { FormSchemaGetter } from '#/adapter/form';
import type { InterviewQuestionForm } from '#/api/interview/question/model';

import { computed, h, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep, listToTree } from '@vben/utils';

// 直接导入而不是动态导入
// eslint-disable-next-line n/no-extraneous-import
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { Button, message } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import { getCategoryList } from '#/api/interview/category';
import {
  addQuestion,
  getQuestionInfo,
  updateQuestion,
} from '#/api/interview/question';

const emit = defineEmits<{ reload: [] }>();

const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});

// 存储分类树数据的引用
const categoryTreeData = ref<any[]>([]);

// AI生成解析
const generateAnalysis = async () => {
  try {
    // 获取当前表单数据
    const formValues = await formApi.getValues();

    if (!formValues.content) {
      message.warning('请先填写题目内容');
      return;
    }

    message.info('正在生成解析，请稍候...');

    // 构造包含分类信息的完整内容
    let fullContent = formValues.content;
    if (formValues.categoryId) {
      // 在树形数据中查找对应的分类名称
      const findCategoryName = (
        categories: any[],
        categoryId: any,
      ): null | string => {
        for (const category of categories) {
          if (category.categoryId == categoryId) {
            return category.fullName || category.categoryName;
          }
          if (category.children && category.children.length > 0) {
            const found = findCategoryName(category.children, categoryId);
            if (found) return found;
          }
        }
        return null;
      };

      const categoryName = findCategoryName(
        categoryTreeData.value,
        formValues.categoryId,
      );
      if (categoryName) {
        fullContent = `题目分类：${categoryName}\n题目内容：${formValues.content}`;
      }
    }

    // 使用 fetchEventSource 处理 SSE 流式响应
    let analysisContent = '';

    await fetchEventSource(
      `${import.meta.env.VITE_GLOB_API_URL || ''}/interview/question/generateAnalysisSse`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'text/event-stream',
          Authorization: `Bearer ${localStorage.getItem('accessToken') || ''}`,
          clientId: import.meta.env.VITE_GLOB_APP_CLIENT_ID || '',
        },
        body: JSON.stringify({ content: fullContent }),
        onmessage(event) {
          // 根据事件类型处理数据
          switch (event.event) {
            case 'content': {
              // 内容事件，累加内容并实时更新
              analysisContent += event.data;
              formApi.setValues({
                analysis: analysisContent,
              });
              // 滚动到解析框和预览框的底部
              scrollToBottom();
              break;
            }

            case 'finish': {
              // 结束事件，使用后端发送的完整内容作为最终结果
              analysisContent = event.data;
              formApi.setValues({
                analysis: analysisContent,
              });
              // 完成后滚动到顶部
              scrollToTop();
              message.success('AI生成解析成功');
              break;
            }

            case 'start': {
              // 开始事件，可以显示初始消息
              message.info(event.data);
              break;
            }

            case 'error': {
              // 错误事件
              throw new Error(event.data);
            }

            default: {
              // 默认处理，累加内容并实时更新
              analysisContent += event.data;
              formApi.setValues({
                analysis: analysisContent,
              });
              // 滚动到解析框和预览框的底部
              scrollToBottom();
            }
          }
        },
        onerror(err) {
          throw err;
        },
      },
    );
  } catch (error) {
    console.error('AI生成解析出错:', error);
    message.error(`AI生成解析出错: ${(error as Error).message}`);
  }
};

// 滚动到解析框和预览框底部的函数
const scrollToBottom = () => {
  // 延迟执行以确保DOM更新完成
  setTimeout(() => {
    // 滚动解析框（textarea）
    const analysisTextarea = document.querySelector(
      'textarea[name="analysis"]',
    );
    if (analysisTextarea) {
      analysisTextarea.scrollTop = analysisTextarea.scrollHeight;
    }

    // 滚动预览框（UaMarkdown组件）
    const markdownPreview = document.querySelector('.ua__markdown');
    if (markdownPreview) {
      markdownPreview.scrollTop = markdownPreview.scrollHeight;
    }
  }, 0);
};

// 滚动到解析框和预览框顶部的函数
const scrollToTop = () => {
  // 延迟执行以确保DOM更新完成
  setTimeout(() => {
    // 滚动解析框（textarea）
    const analysisTextarea = document.querySelector(
      'textarea[name="analysis"]',
    );
    if (analysisTextarea) {
      analysisTextarea.scrollTop = 0;
    }

    // 滚动预览框（UaMarkdown组件）
    const markdownPreview = document.querySelector('.ua__markdown');
    if (markdownPreview) {
      markdownPreview.scrollTop = 0;
    }
  }, 0);
};

// 表单配置
const schemas: FormSchemaGetter = () => [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: [''],
    },
    fieldName: 'questionId',
    label: '面试题ID',
  },
  {
    component: 'TreeSelect',
    fieldName: 'categoryId',
    formItemClass: 'col-span-1',
    label: '所属分类',
    rules: 'required',
    componentProps: {
      placeholder: '请选择所属分类',
      treeData: [],
      fieldNames: { label: 'categoryName', value: 'categoryId' },
      treeDefaultExpandAll: false,
      treeLine: { showLeafIcon: false },
      treeNodeLabelProp: 'fullName',
      showSearch: true,
    },
  },
  {
    component: 'Select',
    formItemClass: 'col-span-1',
    componentProps: {
      options: [
        { label: '简单', value: '简单' },
        { label: '中等', value: '中等' },
        { label: '困难', value: '困难' },
      ],
    },
    defaultValue: '中等',
    fieldName: 'difficulty',
    label: '难度等级',
    rules: 'required',
  },
  {
    component: 'Textarea',
    fieldName: 'content',
    label: '题目内容',
    rules: 'required',
    formItemClass: 'col-span-2',
    style: {
      borderRadius: 'unset',
    },
    componentProps: {
      rows: 1,
      placeholder: '请输入题目内容，支持Markdown语法',
    },
  },
  {
    component: 'Textarea',
    fieldName: 'analysis',
    // 使用函数形式的label，返回包含按钮的虚拟DOM
    label: () =>
      h('div', { style: { display: 'flex', alignItems: 'center' } }, [
        h('span', '解析'),
        h(
          Button,
          {
            type: 'primary',
            size: 'small',
            style: { marginLeft: '10px', barderRadius: '8px' },
            onClick: generateAnalysis,
          },
          'AI生成',
        ),
      ]),
    formItemClass: 'col-span-1',
    componentProps: {
      rows: 4,
      style: {
        minHeight: '400px',
        padding: '10px',
      },
    },
  },
  {
    component: 'UaMarkdown',
    fieldName: 'analysis',
    label: '预览',
    formItemClass: 'col-span-1',
  },
  {
    component: 'RadioGroup',
    formItemClass: 'col-span-1',
    componentProps: {
      options: [
        { label: '是', value: '1' },
        { label: '否', value: '0' },
      ],
    },
    defaultValue: '0',
    fieldName: 'isHot',
    label: '热门推荐',
  },
  {
    component: 'RadioGroup',
    formItemClass: 'col-span-1',
    componentProps: {
      options: [
        { label: '正常', value: '0' },
        { label: '停用', value: '1' },
      ],
    },
    defaultValue: '0',
    fieldName: 'status',
    label: '状态',
    rules: 'required',
  },
  {
    component: 'Select',
    formItemClass: 'col-span-1',
    componentProps: {
      options: [
        { label: '选择题', value: '选择题' },
        { label: '简答题', value: '简答题' },
        { label: '编程题', value: '编程题' },
      ],
    },
    defaultValue: '简答题',
    fieldName: 'type',
    label: '题目类型',
    rules: 'required',
  },
  {
    component: 'Textarea',
    fieldName: 'remark',
    label: '备注',
    formItemClass: 'col-span-1',
  },
];

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    formItemClass: 'col-span-2',
  },
  layout: 'vertical',
  schema: schemas(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});

async function setupCategorySelect() {
  try {
    const res = await getCategoryList({ status: '0' });
    // 转换为树形结构
    const treeData = listToTree(res.rows, {
      id: 'categoryId',
      pid: 'parentId',
      children: 'children',
    });
    // 添加全名，显示层级关系
    addFullName(treeData, 'categoryName', ' / ');

    // 保存分类树数据引用
    categoryTreeData.value = treeData;

    formApi.updateSchema([
      {
        componentProps: {
          treeData,
        },
        fieldName: 'categoryId',
      },
    ]);
  } catch (error) {
    console.error('获取分类列表失败:', error);
  }
}

const [BasicModal, modalApi] = useVbenModal({
  onCancel: handleCancel,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    modalApi.modalLoading(true);
    const { id, update } = modalApi.getData() as {
      id?: number | string;
      update?: boolean;
    };
    isUpdate.value = !!update;

    // 加载分类选项
    await setupCategorySelect();

    if (isUpdate.value && id) {
      const record = await getQuestionInfo(id);
      // 确保在设置值之前等待所有异步操作完成
      await formApi.setValues(record);
    }

    modalApi.modalLoading(false);
  },
});

async function handleConfirm() {
  try {
    modalApi.modalLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    // 确保在获取表单值后再进行类型转换
    await (isUpdate.value
      ? updateQuestion(data as InterviewQuestionForm)
      : addQuestion(data as InterviewQuestionForm));
    emit('reload');
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    modalApi.modalLoading(false);
  }
}

async function handleCancel() {
  modalApi.close();
  await formApi.resetForm();
}
</script>

<template>
  <BasicModal
    :close-on-click-modal="false"
    :title="title"
    :centered="true"
    class="h-[98vh] max-h-[95vh] w-[95%]"
  >
    <BasicForm />
  </BasicModal>
</template>
